<template>
  <v-card outlined class="mb-4">
    <v-card-title>批量上传评估设备</v-card-title>
    <v-card-text>
      <v-file-input
          v-model="selectedFile"
          label="选择 Excel 文件 (.xlsx, .xls)"
          accept=".xlsx, .xls"
          prepend-icon="mdi-microsoft-excel"
          show-size
          :loading="isParsing"
          :disabled="isParsing"
          @change="handleFileChange"
          @click:clear="clearFile"
      ></v-file-input>
      <div v-if="parseError" class="error-message mt-2">{{ parseError }}</div>
      <div class="mt-2 text-caption">
        请确保 Excel 文件包含以下列: 设备名称, 设备型号, 原价值, B1, B2, ..., B10 (列名可略有不同，但顺序和内容需匹配)。
        <br/>
        <a href="/src/assets/docs/template.xlsx" download>下载模板文件</a>
      </div>
    </v-card-text>
  </v-card>
</template>

<script setup>
import { ref } from 'vue';
import * as XLSX from 'xlsx'; // Import xlsx library

const emit = defineEmits(['file-parsed', 'parse-error']); // Define emitted events

const selectedFile = ref(null);
const isParsing = ref(false);
const parseError = ref('');

// Define expected column names (adjust as needed, maybe make configurable)
const EXPECTED_COLUMNS = {
  name: ['设备名称', '名称'],
  model: ['设备型号', '型号'],
  initialValue: ['原价值', '价值'],
  b1: ['B1'], b2: ['B2'], b3: ['B3'], b4: ['B4'], b5: ['B5'],
  b6: ['B6'], b7: ['B7'], b8: ['B8'], b9: ['B9'], b10: ['B10'],
};

// Helper to find the actual column name used in the sheet
function findHeader(headerRow, possibleNames) {
  for (const possibleName of possibleNames) {
    const found = headerRow.find(header => header?.toString().trim() === possibleName);
    if (found) return found;
  }
  return null; // Not found
}


async function handleFileChange() {
  if (!selectedFile.value) {
    clearFile();
    return;
  }
  await parseExcel();
}

function clearFile() {
  selectedFile.value = null;
  parseError.value = '';
  emit('file-parsed', []); // Emit empty array on clear
}


async function parseExcel() {
  if (!selectedFile.value) return;

  isParsing.value = true;
  parseError.value = '';

  try {
    const reader = new FileReader();
    reader.onload = (e) => {
      try {
        const data = new Uint8Array(e.target.result);
        const workbook = XLSX.read(data, { type: 'array' });
        const firstSheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[firstSheetName];

        // Get header row to find actual column names
        const header = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval:'' })[0];
        if (!header || header.length === 0) {
          throw new Error("无法读取表头或工作表为空。");
        }

        // Find actual headers used
        const headers = {
          name: findHeader(header, EXPECTED_COLUMNS.name),
          model: findHeader(header, EXPECTED_COLUMNS.model),
          initialValue: findHeader(header, EXPECTED_COLUMNS.initialValue),
          b1: findHeader(header, EXPECTED_COLUMNS.b1), b2: findHeader(header, EXPECTED_COLUMNS.b2),
          b3: findHeader(header, EXPECTED_COLUMNS.b3), b4: findHeader(header, EXPECTED_COLUMNS.b4),
          b5: findHeader(header, EXPECTED_COLUMNS.b5), b6: findHeader(header, EXPECTED_COLUMNS.b6),
          b7: findHeader(header, EXPECTED_COLUMNS.b7), b8: findHeader(header, EXPECTED_COLUMNS.b8),
          b9: findHeader(header, EXPECTED_COLUMNS.b9), b10: findHeader(header, EXPECTED_COLUMNS.b10),
        };

        // Check if essential headers are found
        const missing = Object.entries(headers).filter(([key, value]) => !value && ['name', 'model', 'initialValue'].includes(key));
        if(missing.length > 0) {
          throw new Error(`缺少必要的列: ${missing.map(m => EXPECTED_COLUMNS[m[0]].join('/')).join(', ')}`);
        }


        // Convert sheet to JSON using the found headers
        const jsonData = XLSX.utils.sheet_to_json(worksheet); // Let sheet_to_json handle headers now

        const parsedDevices = jsonData.map((row, index) => {
          // Basic validation
          const name = row[headers.name]?.toString().trim();
          const model = row[headers.model]?.toString().trim();
          const initialValue = parseFloat(row[headers.initialValue]);

          if (!name || !model || isNaN(initialValue) || initialValue <= 0) {
            console.warn(`Skipping row ${index + 2}: Invalid or missing data (Name: ${name}, Model: ${model}, Value: ${row[headers.initialValue]})`);
            return null; // Skip invalid rows
          }

          const bScores = {};
          let scoreError = false;
          for (let i = 1; i <= 10; i++) {
            const key = `b${i}`;
            if (headers[key]) { // Check if Bx column was found
              const score = parseFloat(row[headers[key]]);
              if (isNaN(score)) {
                console.warn(`Skipping row ${index + 2}: Invalid score for B${i} ('${row[headers[key]]}')`);
                scoreError = true;
                break; // Stop processing scores for this row if one is invalid
              }
              // Optional: Add validation against min/max rules from original component here
              // const rules = validationRules['B'+i];
              // if (rules && (score < rules.min || score > rules.max)) { ... }
              bScores[`B${i}`] = score;
            } else {
              // Handle missing Bx column if required, e.g., set default or throw error
              // bScores[`B${i}`] = null; // Or 0, or skip row
              console.warn(`Row ${index + 2}: Missing expected column B${i}`);
              // Depending on requirements, you might skip the row or proceed with missing data
            }
          }

          if (scoreError) return null; // Skip row if any score was invalid

          return {
            id: `batch-${index}-${Date.now()}`, // Simple unique ID for the batch session
            name: name,
            model: model,
            initialValue: initialValue,
            bScores: bScores, // Store B1-B10 separately
          };
        }).filter(device => device !== null); // Remove skipped rows

        if (parsedDevices.length === 0 && jsonData.length > 0) {
          throw new Error("文件中所有行的数据均无效或格式错误。");
        }
        if (parsedDevices.length === 0) {
          throw new Error("未在文件中找到有效的设备数据。");
        }

        emit('file-parsed', parsedDevices);

      } catch (err) {
        console.error("Excel 解析错误:", err);
        parseError.value = `文件解析失败: ${err.message}`;
        emit('parse-error', err.message);
      } finally {
        isParsing.value = false;
      }
    };

    reader.onerror = (err) => {
      console.error("文件读取错误:", err);
      parseError.value = '读取文件时发生错误。';
      emit('parse-error', '读取文件失败');
      isParsing.value = false;
    };

    reader.readAsArrayBuffer(selectedFile.value); // Read as ArrayBuffer for xlsx library

  } catch (err) {
    console.error("文件处理启动错误:", err);
    parseError.value = `处理文件时出错: ${err.message}`;
    emit('parse-error', `文件处理出错: ${err.message}`);
    isParsing.value = false;
  }
}

</script>

<style scoped>
.error-message {
  color: red;
  font-size: 0.9em;
}
</style>